var CHARSArr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
var $spen_CharWidth;
/*********原生扩展***********/
Date.prototype.format = function (format) {
    var date = {
        "M+": this.getMonth() + 1,
        "d+": this.getDate(),
        "h+": this.getHours(),
        "m+": this.getMinutes(),
        "s+": this.getSeconds(),
        "q+": Math.floor((this.getMonth() + 3) / 3),
        "S+": this.getMilliseconds()
    };
    if (/(y+)/i.test(format)) {
        format = format.replace(RegExp.$1, (this.getFullYear() + '').substr(4 - RegExp.$1.length));
    }
    for (var k in date) {
        if (new RegExp("(" + k + ")").test(format)) {
            format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? date[k] : ("00" + date[k]).substr(("" + date[k]).length));
        }
    }
    return format;
};
// 解决四维运算,js计算失去精度的问题,仅支持5位小数点 
function _fixsStrNUM(n){
    let s = n.toString();
    if(s.indexOf(".") > 0){
        let arr = s.split(".");
        let len = arr[1].length;
        if(len > 10){
            len = 10;
            n = parseFloat(arr[0]+"."+arr[1].substring(0,5));
        }
        return {
            n:n,
            r:len
        }
    }
    return {
        n:n,
        r:1
    };
}
//加法   
Number.prototype.add = function (arg) {
    var r1 = _fixsStrNUM(this);
    var r2 =  _fixsStrNUM(arg);
    var m = r1.r > r2.r ? r1.r : r2.r;  
    m = Math.pow(10,m);
    return (r1.n * m + r2.n * m) / m;
};
//减法   
Number.prototype.sub = function (arg) {
    return this.add(-arg);
};
//乘法   
Number.prototype.mul = function (arg) {
    var m = 0, s1 = this.toString(), s2 = arg.toString();
    try { m += s1.split(".")[1].length } catch (e) { }
    try { m += s2.split(".")[1].length } catch (e) { }
    return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)
};
//除法   
Number.prototype.div = function (arg) {
    var t1 = 0, t2 = 0, r1, r2;
    try { t1 = this.toString().split(".")[1].length } catch (e) { }
    try { t2 = arg.toString().split(".")[1].length } catch (e) { }
    with (Math) {
        r1 = Number(this.toString().replace(".", ""))
        r2 = Number(arg.toString().replace(".", ""))
        return (r1 / r2) * pow(10, t2 - t1);
    }
};
//十六进制颜色值的正则表达式
var HexReg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
/****变量定义******/
var ajaxOpts = {
    waiting: false,
    timeout: 2000 * 60,
    type: "POST",
    dataType: 'json',
    contentType: undefined,
    notEncode: false,
    async: true,
    onErrorEval: false,
    processData: true,
    cache: false,
    dataFilter: undefined,//fn(data, type) 参数过滤处理
    beforeSend: undefined, //fn(xhr, settings) 返回false则不执行
    error: function (xhr, status, errorThrown) {
        this.removeWaiting();
        this.recoverButton();
        var res = status === "timeout" ? "timeout  error!" : "http status " + xhr.status;
        if (window.console) {
            console.log(xhr.responseText);
        }
        try {
            res = eval('(' + xhr.responseText + ')');
        } catch (e) {
        }
        this.onReturn(res, status, xhr);
        this.fail(res, status, xhr);
        this.final(res, status, xhr);
        console.log(xhr.responseText);
    },
    success: function (res, status, xhr) {
        this.removeWaiting();
        this.recoverButton();
        this.onReturn(res, status, xhr);
        if (typeof res.code !== "undefined") {
            if (res.code === 0) {
                var data = res.data;
                if (res.strConvert) {
                    data = eval('(' + res.data + ')');
                }
                this.ok(res.message, data, res);
            } else if (res.code === 99999) {
                if (res.data === "notlogin") {
                    $B.error(res.message);
                    setTimeout(function () {
                        if (window.ctxPath) {
                            window.top.location = $B.getHttpHost(window.ctxPath);
                        }
                    }, 1600);
                } else {
                    var permission = "this is not permission";
                    if ($B.config && $B.config.permission) {
                        permission = $B.config.permission;
                    }
                    $B.error(permission);
                }
            } else {
                this.fail(res.message, res);
            }
        } else {
            this.ok(res, res);
        }
        this.final(res, status, xhr);
    },
    /**
     *当返回结果是正确时的处理
     *data:返回的数据
     *message:提示的信息
     **/
    ok: function (message, data) {
    },
    /***
     *当返回结果是非正确时的处理
     ***/
    fail: function (msg, res) {
        let $b = $B.getBody();
        if ($B.DomUtils.getChildrenByClass($b, "._request_fail_window_").length === 0) {
            let errWin = $B.error(msg, 2);
            $B.DomUtils.addClass(errWin.elObj, "_request_fail_window_");
            if (msg.indexOf("not login") >= 0) {
                window.top.location.href = $B.getHttpHost(window.ctxPath);
            }
        } else {
            console.log(" fail fail 》》》》》》》》》》》》》》》 ", msg, res);
        }
    },
    onReturn: function (res, status, xhr) {
    },
    /**
     * 无论如何都回调的函数
     ****/
    final: function (res, status, xhr) { //无论成功，失败，错误都执行的回调
    },
    recoverButton: function () {
        if (this["target"]) {
            //this["target"].removeAttribute("disabled");
            $B.DomUtils.removeAttribute(this["target"], "disabled");
            $B.DomUtils.html(this["target"], this.recoverText);
            this["target"] = undefined;
        }
    },
    removeWaiting: function () {
        if (this.waiting) {
            this.waiting = undefined;
            this.waitingObj.close();
            this.waitingObj = undefined;
        }
    }
};
_extendObjectFn($B, {
    iframeHtml: "<iframe  class='' frameborder='0' style='overflow:visible;height:100%;width:100%;display:block;vertical-align:top;'  src='' ></iframe>",
    loadingHtml: "<div class='k_box_size k_loading_el' style='position:absolute;z-index:2147483600;width:100%;height:26px;top:2px;left:0;' class='loading'><div class='k_box_size' style='opacity: 0.5;position:absolute;top:0;left:0;width:100%;height:100%;z-index:2147483600;background-color:loadingBackground'></div><div class='k_box_size' style='width:100%;height:100%;line-height:26px;padding-left:16px;position:absolute;width:100%;height:100%;z-index:2147483611;color:#fff;text-align:center;'><i style='color:#fff;font-size:16px;' class='fa animate-spin fa-spin6'></i><span style='padding-left:5px;font-weight:normal;color:#fff;'>loadingTxt</span></div></div>",
    /**框架的ajax统一入口
     *所有ajax返回均以 res={code:'',message:'',data:{}}的格式返回
    *code=0表示服务器无异常运行并返回结果，code=1时，表示服务器出现异常并返回提示
    *message，用与服务器返回的信息提示
    *data,用于服务器返回的数据，如tree组件、datagrid组件返回的数据就保存到data当中
    args={
            waiting:false ,     //是否显示waiting
            timeout: 1000 * 60, //超时
            type: "POST",       //请求方式
            dataType: 'json',   //请求数据类型
            async: true,        //是否异步
            preRequest: fn,     //请求前，回调
            url:'',             //请求url
            data:{},            //请求参数
            ok:function(message,data){},    //成功回调，message:返回信息，data:返回数据
            fail:function(message){},       //失败回调，message:返回信息
            final:function(res){}           //无论成功/失败都调用的回调 res = {code:'',message:'',data:{}}
    }
    ****/
    request: function () {
        var args = arguments[0];
        var opts;
        if (args !== undefined) {
            opts = _extendObjectFn({}, ajaxOpts, args);
        } else {
            opts = ajaxOpts;
        }
        if (opts.data && typeof opts.data === "object" && opts.data.constructor.name !== "FormData") {
            for (var prop in opts.data) {
                if (opts.data[prop] === null) {
                    delete opts.data[prop];
                } else {
                    if (opts.notEncode) {
                        opts.data[prop] = opts.data[prop];
                    } else {
                        opts.data[prop] = this.htmlEncode(opts.data[prop]);
                    }
                }
            }
        }
        var queue = window["_submit_queues"];
        var submitBtn;
        if (queue && queue.length > 0) {
            let lastIdx = queue.length - 1;
            let diff = queue[lastIdx].date - new Date();
            if (diff <= 500) {//500毫秒内
                submitBtn = queue[lastIdx].btn;
                let q = queue.shift();
                q.btn = undefined;
            }
        }
        if (arguments.length > 1 || submitBtn) {
            let btn = arguments.length > 1 ? arguments[1] : submitBtn;
            opts["target"] = btn;
            $B.DomUtils.attribute(btn, { "disabled": "disabled" });
            let busyIng = "this is processing!";
            if ($B.config && $B.config.busyTipTitle) {
                busyIng = $B.config.busyTipTitle;
            }
            if (btn.nodeName === "INPUT") {
                opts["recoverText"] = btn.innerText;
                btn.val(busyIng);
            } else {
                opts["recoverText"] = btn.innerHTML;
                let color = btn.style.color;
                if (btn.lastChild) {
                    color = btn.lastChild.style.color;
                }
                btn.innerHTML = "<i style='padding:0;color:" + color + ";' class='fa fa-spin6 animate-spin'></i><span style='color:" + color + ";padding-left:5px;'>" + busyIng + "</span>";
            }
        }
        if (opts.waiting) {
            let $w = $B.busyTip({});
            opts.waitingObj = $w;
        }
        $B.ajax(opts);
    },
    forbidSelected: function () {
        document.selection && document.selection.empty && (document.selection.empty(), 1)
            || window.getSelection && window.getSelection().removeAllRanges();
    },
    _getSuitablePos: function ($wrap, targetel, $body) {
        let top, left, arrowLeft, maxHeight;
        let wrapWidth = $B.DomUtils.outerWidth($wrap);
        let fixWidth = $B.DomUtils.attribute(targetel, "fix_width");
        let wrapHeight = $B.DomUtils.outerHeight($wrap);
        if ($B.DomUtils.hasClass($wrap, "k_dropdown_list_wrap")) {
            let childLen = $B.DomUtils.attribute($wrap, "_itlen");
            if (childLen) {
                wrapHeight = 24 * parseInt(childLen);
            } else {
                let itWrap = $wrap.lastChild.firstChild.firstChild;
                if (itWrap.children && itWrap.children.length > 0) {
                    wrapHeight = 24 * itWrap.children.length;
                }
            }
            wrapHeight = wrapHeight + 2;
        }

        let elPos = $B.DomUtils.offset(targetel);
        let elHeight = $B.DomUtils.outerHeight(targetel);
        let elWidth = $B.DomUtils.outerWidth(targetel);
        if (fixWidth) {
            elWidth = parseFloat(fixWidth);
        }
        let bodyHeight = $body.clientHeight;
        let bodyWidth = $body.clientWidth;
        // var scrollTop = $B.DomUtils.scrollTop($body);
        // var scrollLeft = $B.DomUtils.scrollLeft($body);
        // elPos.top = elPos.top - scrollTop;
        // elPos.left = elPos.left - scrollLeft;
        //console.log(" _getSuitablePos = " + JSON.stringify(elPos));


        //先检测右下方是否够空间，确认top位置
        let aviHeight = bodyHeight - elPos.top - elHeight;
        let arrowCss = {};
        if (aviHeight >= wrapHeight || elPos.top < aviHeight) {//空间够
            top = elPos.top + elHeight + 8;
            arrowCss["top"] = -14;
            maxHeight = bodyHeight - top - 5;
            arrowCss["transform"] = "rotate(0)";
        } else if ((elPos.top - 6) > aviHeight) {//上面空间比下面的大
            top = elPos.top - wrapHeight - 6;
            arrowCss["bottom"] = -14;
            arrowCss["transform"] = "rotate(180deg)";
            if (top < 2) {
                top = 2;
            }
            maxHeight = elPos.top - 10;
        } else {
            wrapHeight = aviHeight - 8;
            top = elPos.top + elHeight + 8;
            arrowCss["top"] = -14;
            maxHeight = bodyHeight - top - 5;
            arrowCss["transform"] = "rotate(0)";
        }
        let wwWidth = wrapWidth;
        if (wrapWidth < elWidth) {
            wwWidth = elWidth;
        }
        let suitableWidth = bodyWidth * 0.45;
        let needFix2px = false;
        if (wwWidth > suitableWidth) {
            wwWidth = suitableWidth;
            needFix2px = true;
        }
        left = elPos.left;
        //检测合适的left,这里有问题，需要修正
        // left = elPos.left + parseInt(elWidth / 2) - parseInt(wwWidth / 2);
        // if (left < 2) {
        //     left = 2;
        // } else if ((left + wwWidth) > bodyWidth) {
        //     left = bodyWidth - wwWidth;
        // }
        // if (needFix2px) {
        //     left = left - 2;
        // }
        arrowLeft = elPos.left - left + elWidth / 2 - 9;
        arrowCss["left"] = arrowLeft;
        var res = { arrowPos: arrowCss, pos: { top: top, left: left, width: wwWidth, height: wrapHeight, "max-height": maxHeight } };
        return res;
    },
    _createDropListItems: function (items, opts, $inner, $input, resetHeight) {
        $inner.innerHTML = "";
        if (items.length === 0) {
            let nodata = ($B.config && $B.config.returnEmptyData) ? $B.config.returnEmptyData : 'the return is empty!';
            $inner.innerHTML = "<div style='padding-top:6px' class='k_dropdown_list_item not_data'><i style='color:#FF6D34' class='fa fa-info'></i><span style='padding-left:10px;color:#666;'>" + nodata + "</span></div>";
        } else {
            let wrap = $inner;
            let height = 0;
            for (let i = 0; i < items.length; i++) {
                let txt = opts.textField ? items[i][opts.textField] : items[i].text;
                let id = opts.idField ? items[i][opts.idField] : items[i].id;
                id = id + "";
                let $it = $B.DomUtils.append(wrap, "<div class='k_dropdown_list_item'>" + txt + "</div>");
                $B.DomUtils.attribute($it, { dataid: id });
                if (items[i].selected) {
                    $B.DomUtils.addClass($it, "k_dropdown_item_selected");
                    if ($input) {
                        if (!$B.DomUtils.attribute($input, "readonly") && !$B.DomUtils.attribute($input, "multiple")) {
                            $input.value = items[i].text;
                        }
                        if (opts.multiple || Array.isArray($input.selectedValue)) {
                            let put = true;
                            if (!Array.isArray($input.selectedValue)) {
                                $input.selectedValue = [];
                            } else {
                                let varr = $input.selectedValue;
                                for (let j = 0; j < varr.length; j++) {
                                    if (varr[j].id === id) {
                                        put = false;
                                        break;
                                    }
                                }
                            }
                            if (put) {
                                $input.selectedValue.push({ id: id, text: txt });
                            }
                        } else {
                            $input.selectedValue = [{ id: id, text: txt }];
                        }
                    }
                }
                height = height + 24;
            }
            if (resetHeight) {
                var ddlEl = $inner.parentNode.parentNode.parentNode;
                if ($B.DomUtils.css(ddlEl, "display") === "block") {
                    let body = $B.getBody();
                    let pos = $B.DomUtils.position(ddlEl);
                    let aviHeight = $B.DomUtils.height(body) - pos.top - 10;
                    if (height > aviHeight) {
                        height = aviHeight;
                    }
                    $B.DomUtils.height(ddlEl, height + 2);
                }
            }
        }

    },
    createGlobalBodyHideEv: function () {
        var $body = $B.getBody();
        if (!$B.DomUtils.attribute($body, "has_globel_droplist")) {
            $B.DomUtils.attribute($body, { "has_globel_droplist": 1 });
            $B.DomUtils.mousedown($body, (e) => {
                if (window["_globalDraging"]) {
                    return true;
                }
                let target = e.target;
                while (target) {
                    if (target === $B._0001currentdroplistEl) {
                        $B._0001currentdroplistEl = undefined;
                        return true;
                    }
                    if ($B.DomUtils.hasClass(target, "k_dropdown_list_wrap")) {
                        return true;
                    }
                    target = target.parentNode;
                    if (target.nodeName === "#document" || target.tagName === "BODY") {
                        break;
                    }
                }
                let elArr = $B.DomUtils.children($body, ".k_dropdown_list_wrap");
                if (elArr.length > 0) {
                    for (let i = 0; i < elArr.length; i++) {
                        let el = elArr[i];
                        if (el.style.display !== "none") {
                            $B.slideUp(el, 150);
                            let _dlistgid = $B.DomUtils.attribute(el, "_dlistgid");
                            if (_dlistgid) {
                                let $i = document.getElementById(_dlistgid);
                                if ($i) {
                                    let $ic = $B.DomUtils.children($i, "i");
                                    if ($ic.length > 0) {
                                        $B.animate($ic[0], { "rotateZ": "0deg" }, { duration: 200 });
                                    }
                                }
                            }
                        }
                    }
                }
            });
            let elCachedArr = [], cachedTimer;
            $B.DomUtils.resize(window, (e) => {
                cachedTimer = setTimeout(() => {
                    elCachedArr = [];
                }, 1000);
                if (elCachedArr.length > 0) {
                    for (let i = 0; i < elCachedArr.length; i++) {
                        let el = elCachedArr[i].el;
                        let srcEl = elCachedArr[i].srcEl;
                        let ofs = $B.DomUtils.offset(srcEl);
                        let left = ofs.left;
                        el.style.left = left + "px";
                    }
                } else {
                    let allDdls = $B.DomUtils.children($body, ".k_dropdown_list_wrap");
                    for (let i = 0; i < allDdls.length; i++) {
                        let el = allDdls[i];
                        if (!$B.DomUtils.isHide(el)) {
                            let elId = $B.DomUtils.attribute(el, "_dlistgid");
                            let srcEl = document.getElementById(elId);
                            if (srcEl) {
                                let ofs = $B.DomUtils.offset(srcEl);
                                let left = ofs.left;
                                el.style.left = left + "px";
                                elCachedArr.push({
                                    el: el,
                                    srcEl: srcEl
                                });
                            }
                        }
                    }
                }

            });
        }
    },
    /***
     * el:需要下拉选项的元素
     * items:[{id:id,text:txt,selected:true}]
     * opts:{onClick:fn,        //返回true则执行自动关闭
     *       onCreate:fn,
     *       textField，
     *       idField   
     *       motionless:true    是否静默
     *       multiple:false     是否多选
     *       isTree:false       是否树形
     * }
     * ****/
    createDropList: function (el, items, opts) {
        if (Array.isArray(el)) {
            el = el[0];
        }
        var $wrap;
        var $body = $B.getBody();
        this.createGlobalBodyHideEv();
        var $icon = $B.DomUtils.children(el, "i");
        let globalDownid = $B.DomUtils.attribute(el, "_droplistid");
        if (!globalDownid) {
            let id = $B.getUUID();
            $B.DomUtils.attribute(el, { "_droplistid": id });
            $wrap = $B.DomUtils.createEl("<div style='padding:0;margin:0;width:auto;display:none;z-index:" + $B.config.maxZindex + ";top:-100000px;position:absolute;' id='" + id + "' class='k_dropdown_list_wrap k_box_size'></div>");
            let targetid = $B.DomUtils.attribute(el, "id");
            if (!targetid) {
                targetid = $B.getUUID();
                $B.DomUtils.attribute(el, { "id": targetid });
            }
            $B.DomUtils.attribute($wrap, { "_dlistgid": targetid });
            let $inner = $B.DomUtils.createEl("<div class='k_dropdown_inner' style='position:absolute;top:-1000000000px;width:auto;padding:0;margin:0;'></div>");
            let $input = el.firstChild;
            if ($input.tagName !== "INPUT" && $B.DomUtils.attribute($input, "type") !== "text") {
                $input = undefined;
            }
            if (!opts.onCreate) {
                this._createDropListItems(items, opts, $inner, $input);//
            }
            let defautlClick = true;
            if (opts.onCreate) {
                let ret = opts.onCreate(items, opts, $inner, $input);
                if (typeof ret !== "undefined") {
                    if ($B.isPlainObjectFn(ret)) {
                        defautlClick = ret.defautlClick;
                        $B.DomUtils.attribute($wrap, { "_itlen": ret._itlen });
                    } else {
                        defautlClick = ret;
                    }
                }
            }
            $B.DomUtils.append($body, $inner);
            let h = $B.DomUtils.outerHeight($inner);
            let w = $B.DomUtils.outerWidth($inner);
            if (h < 30) {
                h = 30;
            }
            $B.DomUtils.css($wrap, { width: w + 2, height: h + 2 });
            $B.DomUtils.detach($inner);
            $B.DomUtils.removeAttribute($inner, "style");
            $B.DomUtils.css($inner, { height: '100%', width: '100%' });
            $B.DomUtils.append($wrap, $inner);
            $B.myScrollbar($inner, {});
            $B.DomUtils.prepend($wrap, "<div style='position:absolute;width:12px;' class='_droplist_attrow'><i style='font-size:18px;' class='fa fa-up-dir'></i></div>");
            $B.DomUtils.append($body, $wrap);
            $B.DomUtils.mousedown(el, function () {
                $B._0001currentdroplistEl = this;
            });
            if (defautlClick) {
                $B.DomUtils.click($inner, (e) => {
                    if ($B.DomUtils.hasClass(e.target, "not_data")) {
                        return true;
                    }
                    if ($B.DomUtils.hasClass(e.target, "k_dropdown_list_item")) {
                        let id = $B.DomUtils.attribute(e.target, "dataid");
                        let data = { id: id, text: e.target.innerText };
                        let isSelected = true;
                        if (opts.multiple) { //如果是多选
                            if ($B.DomUtils.hasClass(e.target, "k_dropdown_item_selected")) {
                                $B.DomUtils.removeClass(e.target, "k_dropdown_item_selected");
                                isSelected = false;
                            } else {
                                $B.DomUtils.addClass(e.target, "k_dropdown_item_selected");
                            }
                        } else {
                            let siglings = $B.DomUtils.siblings(e.target);
                            for (let i = 0; i < siglings.length; i++) {
                                if ($B.DomUtils.hasClass(siglings[i], "k_dropdown_item_selected")) {
                                    $B.DomUtils.removeClass(siglings[i], "k_dropdown_item_selected");
                                    break;
                                }
                            }
                            $B.DomUtils.addClass(e.target, "k_dropdown_item_selected");
                        }
                        if (opts.onClick) {
                            setTimeout(() => {
                                if (opts.onClick(data, e.target, isSelected)) {
                                    if ($icon.length > 0) {
                                        $B.animate($icon[0], { "rotateZ": "0deg" }, { duration: 200 });
                                    }
                                    $B.fadeOut($wrap, 260);
                                }
                            }, 1);
                        } else {
                            if ($icon.length > 0) {
                                $B.animate($icon[0], { "rotateZ": "0deg" }, { duration: 200 });
                            }
                            $B.fadeOut($wrap, 260);
                        }
                    }
                });
            }
            $B.DomUtils.click(el, function () {
                $B.createDropList(this);
                if ($B.DomUtils.hasClass(this, "k_combox_wrap")) {
                    if (!$B.DomUtils.attribute(this.firstChild, "readonly")) {
                        this.firstChild.focus();
                    }
                }
            });
            $wrap.hideFn = function () {
                $B.fadeOut(this, 260);
                if ($icon.length > 0) {
                    $B.animate($icon[0], { "rotateZ": "0deg" }, { duration: 200 });
                }
            };
            $wrap.showFn = function () {
                if ($B.DomUtils.css(this, "display") === "none") {
                    $B.createDropList(el);
                }
            };
            $wrap.unSelectedFn = function (dataid) {
                let childs = this.lastChild.firstChild.firstChild.children;
                for (let i = 0; i < childs.length; i++) {
                    if (dataid === $B.DomUtils.attribute(childs[i], "dataid")) {
                        $B.DomUtils.removeClass(childs[i], "k_dropdown_item_selected")
                        break;
                    }
                }
            };
            $wrap.selectedFn = function (dataid) {
                let childs = this.lastChild.firstChild.firstChild.children;
                for (let i = 0; i < childs.length; i++) {
                    if (dataid === $B.DomUtils.attribute(childs[i], "dataid")) {
                        $B.DomUtils.addClass(childs[i], "k_dropdown_item_selected")
                        break;
                    }
                }
            };
            $wrap._clearAllFn = function () {
                $wrap.hideFn = undefined;
                $wrap.showFn = undefined;
                $wrap.selectedFn = undefined;
                $wrap.unSelectedFn = undefined;
                $wrap._clearAllFn = undefined;
                $wrap.clearAll = undefined;
            };
            $wrap.clearAll = $wrap._clearAllFn;
        } else {
            $wrap = $B.DomUtils.children($body, "#" + globalDownid);
            if ($B.DomUtils.css($wrap, "display") === "block") {
                if ($icon.length > 0) {
                    $B.animate($icon[0], { "rotateZ": "0deg" }, { duration: 200 });
                }
                $B.fadeOut($wrap, 260);
                return;
            }
        }
        if (opts && opts.motionless) {
            return $wrap;
        }
        if ($wrap) {
            if ($B.DomUtils.css($wrap, "display") === "none") {
                $B.DomUtils.css($wrap, { "display": "block", "top": "-99999999px" });
            }
            let ret = this._getSuitablePos($wrap, el, $body);
            let $arrow = $B.DomUtils.children($wrap, "._droplist_attrow")[0];
            $B.DomUtils.css($arrow, ret.arrowPos);
            let styleAttr = $B.DomUtils.attribute($arrow, "style");
            let styleObj = $B.style2cssObj(styleAttr);
            if (ret.arrowPos.top) {
                delete styleObj.bottom;
            } else {
                delete styleObj.top;
            }
            styleAttr = $B.cssObj2string(styleObj);
            $B.DomUtils.attribute($arrow, { "style": styleAttr });
            $B.DomUtils.css($wrap, ret.pos);
            $wrap = $B.DomUtils.detach($wrap);
            $B.DomUtils.append($body, $wrap);
            if ($icon.length > 0) {
                $B.animate($icon[0], { "rotateZ": "180deg" }, { duration: 200 });
            }
            let $c = $wrap.lastChild.firstChild.firstChild;
            if ($c.children && $c.children.length > 0) {
                for (let i = 0; i < $c.children.length; i++) {
                    $c.children[i].style.display = "block";
                }
            }
            $B.fadeIn($wrap, 260, function () {
                //获取所有项目的最大宽度，设置每一个项目的width为最大宽度
                let $iner = $wrap.lastChild;
                let tmpArr = $B.DomUtils.children($iner.firstChild.firstChild);
                let maxWidth = 0;
                for (let i = 0; i < tmpArr.length; i++) {
                    if (tmpArr[i].scrollWidth > maxWidth) {
                        maxWidth = tmpArr[i].scrollWidth;
                    }
                }
                if (maxWidth > ret.pos.width) {
                    maxWidth = maxWidth + "px";
                    for (let i = 0; i < tmpArr.length; i++) {
                        tmpArr[i].style.width = maxWidth;
                    }
                }
            });
        }
        return $wrap;
    },
    params2urlString: function (params, encode) {
        if (typeof encode === "undefined") {
            encode = true;
        }
        let keys = Object.keys(params);
        let res = [], val;
        for (let i = 0; i < keys.length; i++) {
            if (encode) {
                val = encodeURIComponent(params[keys[i]]);
            } else {
                val = params[keys[i]];
            }
            res.push(keys[i] + "=" + val);
        }
        res.join("&");
    },
    getIframeEl: function (clazz) {
        var el = $B.DomUtils.createEl($B.iframeHtml);
        if (clazz) {
            $B.DomUtils.addClass(el, clazz);
        }
        return el;
    },
    getIconLoading: function (clazz) {
        let el = $B.DomUtils.createEl("<div class=''><i style='font-size:16px' class='fa fa-spin5'></i></div>");
        if (typeof clazz === "string") {
            $B.DomUtils.addClass(el, clazz);
        } else if ($B.isPlainObjectFn(clazz)) {
            let i = $B.children(el, "i");
            $B.DomUtils.css(i, clazz);
        }
        return el;
    },
    getLoadingEl: function (text, background) {
        let cfg = $B.getLoadingCfg();
        if (!text) {
            text = cfg.text;
        }
        if (!background) {
            background = cfg.color;
        }
        var html = $B.loadingHtml.replace("loadingTxt", text);
        if (background) {
            html = html.replace("loadingBackground", background);
        }
        let el = $B.DomUtils.createEl(html);
        let isDeep = this.isDeepColor(background);
        if (!isDeep) {
            let childs = $B.DomUtils.children(el)[1];
            $B.DomUtils.css(childs, { color: "#666" });
            childs = $B.DomUtils.children(childs);
            $B.DomUtils.css(childs, { color: "#666" });
        }
        return el;
    },
    getLoadingCfg: function () {
        let config = $B["config"];
        let loadingBackground = "#5D39F0";
        let loadingTxt = "this is loading , please waiting!";
        if (config) {
            if (config.loadingBackground) {
                loadingBackground = config.loadingBackground;
            }
            if (config.loading) {
                loadingTxt = config.loading;
            }
        }
        return {
            color: loadingBackground,
            text: loadingTxt
        };
    },
    removeLoading: function (loading, fn) {
        $B.fadeOut(loading, () => {
            $B.DomUtils.remove(loading);
            if (fn) {
                fn();
            }
        }, 200);
    },
    getCharWidth: function (text, fs) {
        if (typeof fs === 'undefined') {
            fs = 14;
        }
        if (!$spen_CharWidth) {
            $spen_CharWidth = $B.DomUtils.createEl("<span style='position:absolute;white-space:nowrap;top:-90000000px;left:10000000px'></span>");
            $B.DomUtils.append($B.getBody(), $spen_CharWidth);
        }
        $spen_CharWidth.style.fontSize = fs + "px";
        var w = 0;
        try {
            $spen_CharWidth.innerText = this.htmlEncode(text);
            w = Math.ceil($B.DomUtils.width($spen_CharWidth));
            setTimeout(function () {
                $spen_CharWidth.innerText = "";
            }, 1);
        } catch (ex) {
            console.log(ex);
        }
        return w;
    },
    /***
     * 是否是深色
     * color: 颜色，支持十六进制或者rgba格式
     * ***/
    isDeepColor: function (color) {
        if (color === "none") {
            return false;
        }
        var tempArray
        if (color.indexOf("#") >= 0) {
            color = $B.hex2RgbObj(color);
            tempArray = [];
            tempArray.push(color.r);
            tempArray.push(color.g);
            tempArray.push(color.b);
        } else {
            let rgbval = color.replace("rgb(", "").replace(")", "");
            tempArray = rgbval.split(",");
        }
        var level = tempArray[0] * 0.299 + tempArray[1] * 0.587 + tempArray[2] * 0.114;
        if (level <= 180) {
            return true;
        } else {
            return false;
        }
    },
    rgb2Hsb: function (arg) {
        var rgb = arg;
        if (typeof rgb === "string") {

        }
        var hsb = {
            h: 0,
            s: 0,
            b: 0
        };
        var min = Math.min(rgb.r, rgb.g, rgb.b);
        var max = Math.max(rgb.r, rgb.g, rgb.b);
        var delta = max - min;
        hsb.b = max;
        hsb.s = max !== 0 ? 255 * delta / max : 0;
        if (hsb.s !== 0) {
            if (rgb.r === max) {
                hsb.h = (rgb.g - rgb.b) / delta;
            } else if (rgb.g === max) {
                hsb.h = 2 + (rgb.b - rgb.r) / delta;
            } else {
                hsb.h = 4 + (rgb.r - rgb.g) / delta;
            }
        } else {
            hsb.h = -1;
        }
        hsb.h *= 60;
        if (hsb.h < 0) {
            hsb.h += 360;
        }
        hsb.s *= 100 / 255;
        hsb.b *= 100 / 255;
        return hsb;
    },
    hex2Hsb: function (hex) {
        var hsb = this.rgb2Hsb(this.hex2RgbObj(hex));
        if (hsb.s === 0) {
            hsb.h = 360;
        }
        return hsb;
    },
    hsb2Hex: function (hsb) {
        return this.rgb2Hex(this.hsb2Rgb(hsb));
    },
    hsb2Rgb: function (hsb) {
        var rgb = {};
        var h = Math.round(hsb.h);
        var s = Math.round(hsb.s * 255 / 100);
        var v = Math.round(hsb.b * 255 / 100);
        if (s === 0) {
            rgb.r = rgb.g = rgb.b = v;
        } else {
            var t1 = v;
            var t2 = (255 - s) * v / 255;
            var t3 = (t1 - t2) * (h % 60) / 60;
            if (h === 360) {
                h = 0;
            }
            if (h < 60) {
                rgb.r = t1;
                rgb.b = t2;
                rgb.g = t2 + t3;
            } else if (h < 120) {
                rgb.g = t1;
                rgb.b = t2;
                rgb.r = t1 - t3;
            } else if (h < 180) {
                rgb.g = t1;
                rgb.r = t2;
                rgb.b = t2 + t3;
            } else if (h < 240) {
                rgb.b = t1;
                rgb.r = t2;
                rgb.g = t1 - t3;
            } else if (h < 300) {
                rgb.b = t1;
                rgb.g = t2;
                rgb.r = t2 + t3;
            } else if (h < 360) {
                rgb.r = t1;
                rgb.g = t2;
                rgb.b = t1 - t3;
            } else {
                rgb.r = 0;
                rgb.g = 0;
                rgb.b = 0;
            }
        }
        return {
            r: Math.round(rgb.r),
            g: Math.round(rgb.g),
            b: Math.round(rgb.b)
        };
    },
    /***
     * rgba颜色转十六进制
     * ****/
    rgb2Hex: function (rgbColor) {
        var that = rgbColor;
        if (/^(rgb|RGB)/.test(that)) {
            var aColor = that.replace(/(?:\(|\)|rgb(a)?|RGB(A)?)*/g, "").split(",");
            var strHex = "#";
            let len = aColor.length;
            if (len > 3) {
                len = 3;
            }
            for (var i = 0; i < len; i++) {
                var hex = Number(aColor[i]).toString(16);
                if (hex.length === 1) {
                    hex = "0" + hex;
                }
                if (hex === "0") {
                    hex += hex;
                }
                strHex += hex;
            }
            if (strHex.length !== 7) {
                strHex = that;
            }
            return strHex.toUpperCase();
        } else if (HexReg.test(that)) {
            var aNum = that.replace(/#/, "").split("");
            if (aNum.length === 6) {
                return that.toUpperCase();
            } else if (aNum.length === 3) {
                var numHex = "#";
                for (var j = 0; j < aNum.length; j += 1) {
                    numHex += (aNum[j] + aNum[j]);
                }
                return numHex.toUpperCase();
            }
        } else if ($B.isPlainObjectFn(that)) {
            var hex = [
                that.r.toString(16),
                that.g.toString(16),
                that.b.toString(16)
            ];
            for (let i = 0; i < hex.length; i++) {
                let val = hex[i];
                if (val.length === 1) {
                    hex[i] = '0' + val;
                }
            }
            if (typeof that.a !== "undefined") {
                hex.push(that.a);
            }
            return '#' + hex.join('');
        } else {
            return that.toUpperCase();
        }
    },
    /**
     * 十六进制转rgba object对象
     * ***/
    hex2RgbObj: function (hexColor) {
        if (HexReg.test(hexColor)) {
            if (hexColor.length === 4) {
                var sColorNew = "#";
                for (var i = 1; i < 4; i += 1) {
                    sColorNew += hexColor.slice(i, i + 1).concat(hexColor.slice(i, i + 1));
                }
                hexColor = sColorNew;
            }
            //处理六位的颜色值
            var sColorChange = [];
            for (var j = 1; j < 7; j += 2) {
                sColorChange.push(parseInt("0x" + hexColor.slice(j, j + 2)));
            }
            return {
                r: sColorChange[0],
                g: sColorChange[1],
                b: sColorChange[2]
            };
        }
    },
    /**
  * 十六进制转rgba 字符串
  * ***/
    hex2Rgb: function (hexColor) {
        var rgbObj = this.hex2RgbObj(hexColor);
        if (rgbObj) {
            return "RGB(" + rgbObj.r + "," + rgbObj.g + "," + rgbObj.b + ")";
        }
    },
    rgbaStr2Obj: function (str) {
        let ret = /^rgb|RGB\((\d+),\s*(\d+),\s*(\d+),\s*([0,1]\.\d+)\)$/.exec(str);
        return {
            r: ret[1],
            g: ret[2],
            b: ret[3]
        };
    },
    getContrastColor: function (value) {
        if (!value) {
            return 'rgb(105, 118, 166)';
        }
        var rgb = value;
        if (typeof rgb === "string" && value.toLowerCase().indexOf("rgb") < 0) {
            rgb = this.hex2Rgb(value);
        }
        rgb.r = 255 - rgb.r;
        rgb.g = 255 - rgb.g;
        rgb.b = 255 - rgb.b;
        return ['rgb(', rgb.r, ',', rgb.g, ',', rgb.b, ')'].join('');
    },
    /**
     * 获取当前document的body，并且将其position声明为 relative
     * ***/
    getDomBody: function () {
        if (!$body) {
            $body = document.body.style.position = "relative";
        }
        return $body;
    },
    /****获取的当前浏览器的主机应用地址 *****/
    getHttpHost: function (ctxPath) {
        var proto = window.location.protocol;
        var host = proto + "//" + window.location.host;
        var ctx;
        if (!ctxPath && window.ctxPath) {
            ctx = window.ctxPath;
        } else if (ctxPath) {
            ctx = ctxPath;
        }
        if (ctx) {
            host = host + ctx;
        }
        return host;
    },
    /**
     * 用于优化递归实现的函数
     * ***/
    recursionFn: function (fn, isRemain) {
        var active = false;
        var accumulated = [];
        return function executeFn() {
            if (arguments.length === 1) {
                if (typeof arguments[0] === "string" && arguments[0] === "destroy") {
                    fn = undefined;
                    accumulated = undefined;
                    return;
                }
            }
            accumulated.push(arguments);//每次将参数传入. 例如, 1 100000
            if (!active) {
                active = true;
                while (accumulated.length) {
                    let args = accumulated.pop();
                    fn.apply(this, args);
                }
                active = false;
                if (!isRemain) {
                    fn = undefined;
                }
            }
        };
    },
    /***
     * args={
     *      url:,
     *      success:fn(data, status, xhr)
     *      error:fn(xhr, type, error),
     *      complete:fn()
     * }
     * ***/
    htmlLoad: function (args, targetEl) {
        var loadingEl;
        if (targetEl) {
            let el = $B.DomUtils.children(targetEl, ".k_loading_el");
            if (el.length === 0) {
                loadingEl = $B.getLoadingEl();
                $B.DomUtils.append(targetEl, loadingEl);
            }
            let p = $B.DomUtils.children(targetEl, ".k_req_error_p");
            $B.DomUtils.remove(p);
        }
        var defopt = {
            success: function (data, status, xhr) {
                if (targetEl) {
                    targetEl.innerHTML = data;
                }
            },
            error: function (xhr, type, error) {
                if (targetEl) {
                    targetEl.innerHTML = "<p class='k_req_error_p' style='text-align:center;'><i style='color:#D6D603' class='fa fa-attention'></i><span style='padding-left:10px'>" + xhr.statusText + "：" + xhr.status + "</span></p>";
                }
            },
            complete: function () {
                if (loadingEl) {
                    $B.removeLoading(loadingEl);
                }
            }
        };
        var opt;
        if (typeof args === "string") {
            opt = defopt;
            opt["url"] = args;
        } else {
            opt = $B.extendObjectFn({}, defopt, args);
        }
        $B.ajax(opt);
    },
    /**返回当前时间的格式化***/
    formateNow: function (format) {
        if (!format) {
            format = "yyyyMMddhhmmss";
        }
        return this.formateDate(new Date(), format);
    },
    /***格式化data***/
    formateDate: function (date, format) {
        return date.format(format);
    },
    /***生成随机数***/
    random: function (lower, upper) {
        if (!lower) {
            lower = 0;
        }
        if (!upper) {
            upper = 10000;
        }
        return Math.floor(Math.random() * (upper - lower)) + lower;
    },
    /***
     * 获取元素el的transform矩阵信息
     * ****/
    getMatrixArray: function (el) {
        var res;
        var matrix = el.style["transform"];
        if (matrix && matrix !== "none") {
            var values = matrix.split('(')[1].split(')')[0].split(',');
            res = [];
            for (var i = 0; i < values.length; i++) {
                res.push(parseFloat(values[i]));
            }
        }
        return res;
    },
    /**获取元素旋转后的位置偏移量**/
    getAnglePositionOffset: function (el) {
        var ofs = { fixTop: 0, fixLeft: 0 };
        var matrixArr = this.getMatrixArray(el);
        if (matrixArr) {
            var pos = $B.DomUtils.position(el);
            var angle = $B.getMatrixAngle(matrixArr);
            if (angle !== 0) {
                var clone = document.createElement("div");
                var style = el.getAttribute("style");
                clone.setAttribute("style", style);
                $B.DomUtils.css(clone, { "transform": "rotate(0deg)", "opacity": "0", "position": "absolute", "z-index": -111 });
                el.parentNode.append(clone);
                var clonePos = $B.DomUtils.position(clone);
                ofs.fixTop = clonePos.top - pos.top;
                ofs.fixLeft = -(pos.left - clonePos.left);
                el.parentNode.removeChild(clone);
            }
        }
        return ofs;
    },
    /**
    * 获取旋转的角度
    * matrix = css("transform")
    * **/
    getMatrixAngle: function (matrixArr) {
        var a = matrixArr[0];
        var b = matrixArr[1];
        var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
        return angle;
    },
    /***
     * pos 是否在 el元素内
     * pos = {top:,left}
     * el :jq元素
     * ***/
    isInElement: function (pos, el, isRelative) {
        var ofs;
        if (isRelative) {
            ofs = el.position();
        } else {
            ofs = el.offset();
        }
        var w = el.outerWidth();
        var h = el.outerHeight();
        var matrix = $B.getMatrixArray(el);
        if (matrix) { //如果存在缩放               
            var rate = parseFloat(matrix[0]);
            h = h * rate;
            w = w * rate;
        }
        var endTop = ofs.top + h;
        var endLeft = ofs.left + w;
        if (pos.top >= ofs.top && pos.top <= endTop && pos.left >= ofs.left && pos.left <= endLeft) {
            return true;
        }
        return false;
    },
    /****
     * 对str字符串进行html符号替换，防止xss
     * *****/
    htmlEncode: function (str) {
        if (!str || typeof str.replace === "undefined") {
            return str;
        }
        var s = "";
        if (str.length === 0) {
            return "";
        }
        // s = str.replace(/%/g,"%25");
        s = str.replace(/</g, "&lt;");
        s = s.replace(/>/g, "&gt;");
        s = s.replace(/eval\((.*)\)/g, "");
        s = s.replace(/<.*script.*>/, "");
        /*双引号 单引号不替换
        s = s.replace(/\'/g,"&#39;");
        s = s.replace(/\"/g,"&quot;");*/
        return s;
    },
    /*****
     * 将html encode替换的符号，恢复
     * ******/
    htmlDecode: function (str) {
        if (typeof str.replace === "undefined") {
            return str;
        }
        var s = "";
        if (str.length === 0) {
            return "";
        }
        s = str.replace(/&amp;/g, "&");
        s = s.replace(/&lt;/g, "<");
        s = s.replace(/&gt;/g, ">");
        s = s.replace(/&#39;/g, "\'");
        s = s.replace(/&quot;/g, "\"");
        return s;
    },
    /**
     * 动态创建页面style样式
     * className：样式class名称
     * styleText：样式内容
     * ***/
    createHeaderStyle: function (className, styleText) {
        var header = document.getElementsByTagName('head')[0];
        this._appendHeaderStyle(header, className, styleText);
    },
    _appendHeaderStyle: function (header, className, styleText) {
        var element;
        var childs = header.children;
        for (var i = 0; i < childs.length; i++) {
            if (childs[i].className === className) {
                element = childs[i];
                break;
            }
        }
        if (element) {
            header.removeChild(element);
        }
        var style = document.createElement('style');
        style.type = "text/css";
        style.className = className;
        style.innerText = styleText;
        header.appendChild(style);
    },
    /***
     * 获取uuid
     * ***/
    getUUID: function () {
        return this.generateDateUUID();
    },
    getIdIdx: function () {
        if (!window["_$_idx_"]) {
            window["_$_idx_"] = 1;
        } else {
            window["_$_idx_"]++;
        }
        return window["_$_idx_"];
    },
    /**
    * 生成短位数的uuid
    * **/
    getShortID: function () {
        var prex = (new Date()).format("hhmmssSS") + this.getIdIdx();
        var str = this.generateMixed(5);
        return "k_" + prex + str;
    },
    /**
     * 生成uuid
     * fmt：格式yyyyMMddhhmmssSSS,
     * count
     * **/
    generateDateUUID: function (fmt, count) {
        var c = count ? count : 5;
        var formt = fmt ? fmt : "yyMMddhhmmssSS";
        var prex = (new Date()).format(formt) + this.getIdIdx();
        return "k_" + prex + this.generateMixed(c);
    },
    /***产生混合随机数
     *@param n 位数 默认6
     ***/
    generateMixed: function (n) {
        var _n = n ? n : 6;
        var res = [];
        for (var i = 0; i < _n; i++) {
            var id = Math.ceil(Math.random() * 35);
            res.push(CHARSArr[id]);
        }
        return res.join("");
    },
    /**是否是url**/
    isUrl: function (str) {
        if (typeof str !== 'string') {
            return false;
        }
        if (str && str.indexOf("/") < 0) {
            return false;
        }
        return /^((http(s)?|ftp):\/\/)?([\w-]+\.)*[\w-]+(\/[\w-.\/?%&=]*)?(:\d+)?/.test(str);
    },
    /**
     * css样式对象转字符串格式
     * ***/
    cssObj2string: function (cssObj) {
        var res = [];
        var keys = Object.keys(cssObj);
        var key;
        for (var i = 0; i < keys.length; i++) {
            key = keys[i];
            res.push(key + ":" + cssObj[key]);
        }
        return res.join(";");
    },
    /****
     * style字符串转css对象
     * ***/
    style2cssObj: function (style) {
        if (typeof style !== "string") {
            style = $B.DomUtils.attribute(style, "style");
        }
        var res = {};
        if (!style || style === "") {
            return res;
        }
        var tmp = style.split(";");
        var oneArr;
        for (var i = 0; i < tmp.length; i++) {
            if (tmp[i] !== "") {
                oneArr = tmp[i].split(":");
                res[$B.trimFn(oneArr[0])] = $B.trimFn(oneArr[1]);
            }
        }
        return res;
    },
    /***
     * 将参数object对象，转为字符串形式
     * dataObj：{}数据对象
     * isMakeRandom：是否形成一个随机参数
     * encodeUrl：是否进行encodeURIComponent
     * ***/
    formatUrlParams: function (dataObj, isMakeRandom, encodeUrl) {
        var arr = [];
        var rnd, encode;
        rnd = typeof isMakeRandom !== "undefined" ? isMakeRandom : false;
        encode = typeof encodeUrl !== "undefined" ? encodeUrl : true;
        let keys = Object.keys(dataObj);
        for (let i = 0; i < keys.length; i++) {
            if (encode) {
                arr.push(encodeURIComponent(keys[i]) + "=" + encodeURIComponent(dataObj[keys[i]]));
            } else {
                arr.push(encodeURIComponent(keys[i]) + "=" + dataObj[keys[i]]);
            }
        }
        if (rnd) {
            arr.push(("_rmd=" + Math.random()).replace(".", ""));
        }
        return arr.join("&");
    },
    isNotEmpty: function (v) {
        return v !== null && typeof v !== 'undefiend' && v !== "";
    },
    /***
    * 写cookie
    * ***/
    writeCookie: function (name, value, expiredays) {
        if (!this.isNotEmpty(expiredays)) {
            expiredays = 1;
        }
        try {
            var exdate = new Date();
            exdate.setDate(exdate.getDate() + expiredays);
            document.cookie = name + "=" + window.escape(value) + ";expires=" + exdate.toGMTString();
        } catch (ex) {
            console.log("write cookied err ", ex);
        }
    },
    /**
     * 读取cookie
     * ***/
    getCookie: function (c_name) {
        if (document.cookie.length > 0) {
            var c_start = document.cookie.indexOf(c_name + "=");
            if (c_start !== -1) {
                c_start = c_start + c_name.length + 1;
                var c_end = document.cookie.indexOf(";", c_start);
                if (c_end === -1) {
                    c_end = document.cookie.length;
                }
                return window.unescape(document.cookie.substring(c_start, c_end));
            }
        }
        return "";
    },
    /**
     * 循环数组
     * ***/
    foreach: function (arr, fn) {
        for (let i = 0; i < arr.length; i++) {
            fn(arr[i]);
        }
    },
    /***
     * 替换换行，回车
     * ***/
    replaceSpaceChar: function (str) {
        var string = str;
        try {
            string = string.replace(/\r\n/g, "");
            string = string.replace(/\n/g, "");
            string = string.replace(/\s+/g, "");
        } catch (e) {
        }
        return string;
    },
    /**获取滚动条宽度**/
    getScrollWidth: function () {
        var key = '_CURRENT_SCROLL_SIZE_';
        if (typeof window[key] !== "undefined") {
            return window[key];
        }
        var noScroll, scroll, oDiv = document.createElement("DIV");
        oDiv.style.cssText = "position:absolute; top:-1000px; width:100px; height:100px; overflow:hidden;";
        noScroll = document.body.appendChild(oDiv).clientWidth;
        oDiv.style.overflowY = "scroll";
        scroll = oDiv.clientWidth;
        document.body.removeChild(oDiv);
        window[key] = noScroll - scroll;
        return window[key];
    },
    vueForm: function (el, bean, formCtls, opts) {
        if (typeof Vue !== "function") {
            console.log("please import vue!");
            alert("please import vue!");
            return;
        }
        var verifyOnChange = opts.verifyOnChange;
        opts.verifyOnChange = false;
        let elId;
        if (typeof el === "string") {
            elId = el.replace("#", "");
            el = document.getElementById(elId);
        } else {
            elId = el.id;
            if(!elId){
                elId = this.getUUID();
                $B.DomUtils.attribute(el, { id: elId });
            }          
        }
        if (!$B.isPlainObjectFn(opts.verify)) {
            opts.verify = {};
        }
        if (!$B.isPlainObjectFn(bean)) {
            bean = {};
        }
        if (!$B.isPlainObjectFn(formCtls)) {
            formCtls = {};
        }
        let formData = {};
        let watch = {};
        let diyCtlArray = [];
        let diyDataBean = {};
        let lableIdMap = {};
        let mouseTipEls = [];
        this._loopFormEl(el, (el) => {
            if (!$B.DomUtils.attribute(el, "not_bind")) {
                let tagName = el.tagName;
                let id = el.id;
                let formName = id;
                let ctlOpt = formCtls[id];               
                if (tagName === "INPUT") {
                    if (ctlOpt) {//如果是自定义的控件
                        diyCtlArray.push({
                            id: id,
                            ctlOpt: ctlOpt
                        });
                        if (ctlOpt.ctl === "Combox") {
                            formData[id] = [];
                        } else if (ctlOpt.ctl === "Calendar") {
                            formData[id] = "";
                        } else if (ctlOpt.ctl === "switchCtl") {
                            if (typeof bean[id] !== "undefined") {
                                formData[id] = bean[id];
                                el.value = bean[id];
                            } else {
                                if (el.value !== "1") {
                                    el.value = 0;
                                    bean[id] = 0;
                                } else if (typeof bean[id] === "undefined") {
                                    bean[id] = el.value;
                                }
                                formData[id] = bean[id];
                            }
                        } else if (ctlOpt.ctl === "NUMInputCtl") {
                            $B.DomUtils.attribute(el, { "v-model": id });
                            let $pan = $B.Dom.after(el, "<span class='k_fnumber_wrap'></span>");
                            el.parentNode.removeChild(el);
                            $B.Dom.append($pan, el);
                            if (typeof bean[id] !== "undefined") {
                                formData[id] = bean[id];
                                el.value = bean[id];
                            } else {
                                formData[id] = 0;
                                el.value = 0;
                            }
                        }
                        diyDataBean[id] = bean[id];
                        delete bean[id];
                    } else {
                        let type = el.type;
                        if (type === "text" || type === "password" || type === "hidden") {
                            if (type === "hidden" && formName.indexOf("old_") === 0) {
                                let fname = formName.replace("old_", "");
                                el.value = bean[fname] ? bean[fname] : "";
                            }
                            formData[id] = el.value;
                            $B.DomUtils.attribute(el, { "v-model": id });
                        } else if (type === "radio") {
                            if (typeof formData[el.name] === "undefined") {
                                formData[el.name] = el.value;
                            }
                            if (el.checked) {
                                formData[el.name] = el.value;
                            }
                            $B.DomUtils.attribute(el, { "v-model": el.name });
                            formName = el.name;
                            if (!lableIdMap[formName]) {
                                lableIdMap[formName] = [];
                            }
                            lableIdMap[formName].push(el);
                        } else if (type === "checkbox") {
                            if (!formData[el.name]) {
                                formData[el.name] = [];
                                if (bean[el.name] && !Array.isArray(bean[el.name])) {
                                    bean[el.name] = bean[el.name].split(";");
                                }
                            }
                            if (el.checked) {
                                formData[el.name].push(el.value);
                            }
                            $B.DomUtils.attribute(el, { "v-model": el.name });
                            formName = el.name;
                            if (!lableIdMap[formName]) {
                                lableIdMap[formName] = [];
                            }
                            lableIdMap[formName].push(el);
                        }
                    }
                } else if (tagName === "TEXTAREA") {
                    formData[id] = el.innerText ? el.innerText : "";
                    $B.DomUtils.attribute(el, { "v-model": id });
                } else if (tagName === "SELECT") {
                    let child = el.children;
                    formData[id] = "";
                    for (let i = 0; i < child.length; i++) {
                        if (child[i].selected) {
                            formData[id] = child[i].value;
                            break;
                        }
                    }
                    $B.DomUtils.attribute(el, { "v-model": id });
                } else if (tagName === "UL") {//树控件
                    if (ctlOpt) {//如果是自定义的控件
                        if (ctlOpt.ctl === "Tree") {
                            formData[id] = undefined;
                        }
                        diyDataBean[id] = bean[id];
                        delete bean[id];
                        diyCtlArray.push({
                            id: id,
                            ctlOpt: ctlOpt
                        });
                    }
                }
                watch[formName] = this._getWatchFn(formName, opts);
                if($B.Dom.attr(el,"tip_lbl")){                   
                    if(!el.id){
                        el.id = $B.getUUID();
                    }
                    mouseTipEls.push(el.id);
                }
            }
        });
        $B.extendObjectFn(formData, bean);
        let lblKeys = Object.keys(lableIdMap);
        for (let i = 0; i < lblKeys.length; i++) {
            let lblName = lblKeys[i];
            let lsEls = lableIdMap[lblName];
            let itEl = lsEls[lsEls.length - 1];
            let pEl = itEl.parentNode;
            if (pEl.tagName === "LABEL") {
                $B.DomUtils.attribute(pEl, { id: "k_lbl_" + lblName });
            } else {
                $B.DomUtils.attribute(itEl, { id: "k_lbl_" + lblName });
            }
        }        
        let vueObj = new Vue({
            el: "#" + elId,
            data: formData,
            watch: watch,
            mounted: function () {
            },
            updated: function () {
                if (opts.onUpateFn) {
                    setTimeout(() => {
                        opts.onUpateFn.call(this);
                    }, 1);
                }
            }
        });
        var onValueChange = function (name, newVal, oldVal) {
            if ($B.isPlainObjectFn(newVal)) {
                newVal = $B.cloneObjectFn(newVal);
            }
            let skipFieldMvm = "_$skip_" + name;
            vueObj[skipFieldMvm] = name;
            formData[name] = newVal;
            setTimeout(() => {
                delete vueObj[skipFieldMvm];
            }, 1);
        };
        //创建自定义控件,控件必须实现onChange，setValue
        let diyCtlMap = {};
        vueObj["_$diyCtlMap"] = diyCtlMap;
        let formEl = document.getElementById(elId);
        opts.$form = formEl;
        for (let i = 0; i < diyCtlArray.length; i++) {
            let ctlEl = $B.DomUtils.findbyId(formEl, diyCtlArray[i].id);
            let ctlOpt = diyCtlArray[i].ctlOpt;
            let ctlName = ctlOpt.ctl;
            if ($B[ctlName]) {
                let ctlObj;
                ctlOpt.opts.onChange = onValueChange;
                if (ctlName.indexOf("Ctl") > 0) {
                    ctlObj = $B[ctlName](ctlEl, ctlOpt.opts);
                } else {
                    ctlObj = new $B[ctlName](ctlEl, ctlOpt.opts);
                }
                diyCtlMap[diyCtlArray[i].id] = ctlObj;
                //修改值以触发自定义控件的ui绑定
                if (diyDataBean[diyCtlArray[i].id]) {
                    formData[diyCtlArray[i].id] = diyDataBean[diyCtlArray[i].id];
                    delete diyDataBean[diyCtlArray[i].id];
                }
            } else {
                console.log("[" + ctlName + "] 没有找到！");
            }
        }
        formData["toJSON"] = function (array2str) {
            let keys = Object.keys(this);
            let res = {};
            for (let i = 0; i < keys.length; i++) {
                let key = keys[i];
                if (typeof this[key] !== "function" && key !== "$form") {
                    if (Array.isArray(this[key])) {
                        if (array2str) {
                            res[key] = $B._arr2str(this[key]);
                        } else {
                            res[key] = [...this[key]];
                        }
                    } else {
                        res[key] = this[key];
                    }
                }
            }
            return res;
        };
        formData["toJSONStr"] = function (array2str) {
            return JSON.stringify(this.toJSON(array2str));
        };
        formData["toDestroy"] = function () {
            opts.verify = undefined;
            let ctls = Object.values(diyCtlMap);
            for (let i = 0; i < ctls.length; i++) {
                ctls[i].destroy();
            }
            vueObj.$destroy();
            vueObj["_$diyCtlMap"] = undefined;
            formData["toDestroy"] = undefined;
            formData["toJSON"] = undefined;
            formData["toJSONStr"] = undefined;
            formData["toVerify"] = undefined;
            formData["$form"] = undefined;
            opts.$form = undefined;
            formData.__ob__ = undefined;
            formData = undefined;
            diyCtlMap = undefined;
            opts = undefined;
            formEl = undefined;
        };
        formData["toVerify"] = function () {
            if ($B.isEmptyObjectFn(opts.verify)) {
                return true;
            }
            let formKeys = Object.keys(opts.verify);
            let isPast = true;
            for (let i = 0; i < formKeys.length; i++) {
                let formName = formKeys[i];
                let value = formData[formName];
                if (typeof value === "undefined") {
                    value = "";
                }
                let vrfCfg = opts.verify[formName];
                let r = $B._exeVerify(formName, value, vrfCfg, formEl);
                if (!r) {
                    isPast = r;
                }
            }
            return isPast;

        };
        setTimeout(() => {
            opts.verifyOnChange = verifyOnChange;
            //鼠标提示支持
            for(let i =0 ; i < mouseTipEls.length ;i++){
                let id = mouseTipEls[i];
                let el = $B.DomUtils.findbyId(formEl,id);
                $B.mouseTip(el, $B.Dom.attr(el,"tip_lbl"), undefined, "#9090C9");
            }
        }, 20);
        this.bindInputClear(formEl, (elName) => {
            if (formData[elName]) {
                formData[elName] = "";
                return true;
            }
            console.log("formData is undefined！");
            return false;
        });
        formData.$form = formEl;      
        return formData;
    },
    /**
 * 创建开关控件
 * @param  el
 * @param  opts {
            trueText:"是",
            falseText:"否",                    
            onChange:(value)=>{
                console.log(value);
            }
        }
    */
    switchCtl: function (el, opts) {
        let id;
        if (typeof el === "string") {
            id = el.replace("#", "");
            el = document.getElementById(id);
        } else {
            let id = $B.DomUtils.attribute(el, "id");
            if (!id) {
                id = "sw_" + $B.getShortID();
                $B.DomUtils.attribute(el, { "id": id });
            }
        }
        let chkCls = "k_switch_core_checked";
        if (el.value === "" || el.value !== "1") {
            el.value = "0";
            chkCls = "";
        }
        let $wrap = $B.DomUtils.createEl("<span class='k_switch_wrap'><span class='k_switch_left_label'></span><span class='k_switch_core " + chkCls + "'></span><span class='k_switch_right_label'></span></span>");
        if (opts.trueText) {
            $wrap.firstChild.innerText = opts.trueText;
            $B.DomUtils.addClass($wrap.firstChild, "k_switch_l_padding");
        }
        if (opts.falseText) {
            $wrap.lastChild.innerText = opts.falseText;
            $B.DomUtils.addClass($wrap.lastChild, "k_switch_r_padding");
        }
        if (chkCls === "") {
            $B.DomUtils.addClass($wrap.lastChild, "k_switch_label_checked");
        } else {
            $B.DomUtils.addClass($wrap.firstChild, "k_switch_label_checked");
        }
        $B.DomUtils.after(el, $wrap);
        $B.DomUtils.remove(el);
        $B.DomUtils.append($wrap, el);
        $B.DomUtils.click($wrap, (e) => {
            let $el = e.target;
            while ($el) {
                if ($B.DomUtils.hasClass($el, "k_switch_wrap")) {
                    break;
                }
                $el = $el.parentNode;
            }
            let childs = $B.DomUtils.children($el, "span");
            let oldClazz = [];
            for (let i = 0; i < childs.length; i++) {
                oldClazz.push($B.DomUtils.attribute(childs[i], "class"));
            }
            let $c = $B.DomUtils.children($el, ".k_switch_core")[0];
            let oldVal = $el.lastChild.value;
            if ($B.DomUtils.hasClass($c, "k_switch_core_checked")) {
                $B.DomUtils.removeClass($c, "k_switch_core_checked");
                $el.lastChild.value = "0";
                $B.DomUtils.removeClass($c.previousSibling, "k_switch_label_checked");
                $B.DomUtils.addClass($c.nextSibling, "k_switch_label_checked");
            } else {
                $B.DomUtils.addClass($c, "k_switch_core_checked");
                $el.lastChild.value = "1";
                $B.DomUtils.addClass($c.previousSibling, "k_switch_label_checked");
                $B.DomUtils.removeClass($c.nextSibling, "k_switch_label_checked");
            }
            if (opts.onChange) {
                opts.onChange.call($el, $el.lastChild.id, $el.lastChild.value, oldVal, oldClazz);
            }
        });
        if (!opts.notReturn) {
            return {
                setValue: function (val, triggerChange) {
                    let isChecked = true;
                    if (typeof val === "boolean") {
                        isChecked = val;
                    } else if (typeof val === "number") {
                        isChecked = val === 1;
                    } else {
                        isChecked = val === "1";
                    }
                    let $c = $B.DomUtils.children($wrap, ".k_switch_core")[0];
                    if (isChecked) {
                        $B.DomUtils.addClass($c, "k_switch_core_checked");
                        $wrap.lastChild.value = "1";
                        $B.DomUtils.addClass($c.previousSibling, "k_switch_label_checked");
                        $B.DomUtils.removeClass($c.nextSibling, "k_switch_label_checked");
                    } else {
                        $B.DomUtils.removeClass($c, "k_switch_core_checked");
                        $wrap.lastChild.value = "0";
                        $B.DomUtils.removeClass($c.previousSibling, "k_switch_label_checked");
                        $B.DomUtils.addClass($c.nextSibling, "k_switch_label_checked");
                    }
                },
                destroy: function () {
                    $B.DomUtils.remove($wrap);
                    opts.onChange = undefined;
                    opts = undefined;
                    this.setValue = undefined;
                    this.destroy = undefined;
                }
            };
        }
    },
    NUMInputCtl: function (el, opts) {       
        if (!$B.Dom.hasClass(el, "k_number_input")) {
            if (!$B.Dom.hasClass(el.parentNode, "k_fnumber_wrap")) {
                let $span = $B.Dom.after(el, "<span class='k_fnumber_wrap'></span>");
                el.parentNode.removeChild(el);
                $B.Dom.append($span, el);
            }
            $B.Dom.addClass(el, "k_number_input");
            let $prt = el.parentNode;
            let btn = $B.Dom.append($prt, "<span style='position:absolute;top:0px;right:2px;display:inline-block;line-height: 12px;' class='up-dir'><i class='fa fa-up-dir'></i></span>");
            let btn1 = $B.Dom.append($prt, "<span style='position:absolute;bottom:0px;right:2px;display:inline-block;line-height: 12px;' class='down-dir'><i class='fa fa-down-dir'></i></span>");
            let clickFN = (e) => {
                let step = 1;
                if (opts.step) {
                    step = parseFloat(opts.step);
                }
                let catpurer = e.catpurer;
                let oldVal = $B.trimFn(el.value);
                if ($B.config.verify.number.reg.test(oldVal)) {
                    oldVal = parseFloat(oldVal);
                } else {
                    oldVal = 0;
                }
                let newVal;
                if ($B.Dom.hasClass(catpurer, "up-dir")) {
                    newVal = oldVal.add(step);
                } else {
                    newVal = oldVal.sub(step);
                }
                if(typeof opts.min !== "undefined"){
                    if(newVal < opts.min){
                        return false;
                    }
                }
                if(typeof opts.max !== "undefined"){
                    if(newVal > opts.max){
                        return false;
                    }
                }
                el.value = newVal;               
                opts.onChange(el.id, newVal, oldVal);                
            };
            $B.Dom.click(btn, clickFN);
            $B.Dom.click(btn1, clickFN);
        }

    },
    _getWatchFn: function (formName, opts) {
        return function (newVal, oldVal) {
            let diyCtlMap = this._$diyCtlMap;
            let diyCtlINS = diyCtlMap[formName];
            if (diyCtlINS) {
                let skipFieldMvm = "_$skip_" + formName;
                if (!this[skipFieldMvm]) {
                    if (diyCtlINS.setValue) {
                        let argsVal = newVal;
                        if (Array.isArray(newVal) || $B.isPlainObjectFn(newVal)) {
                            argsVal = $B.cloneObjectFn(newVal);
                        }
                        diyCtlINS.setValue(argsVal, false);
                    } else {
                        console.log("the ctl not impl setValue!");
                    }
                }
            }
            //值发生变化，可触发验证
            let isError = false;
            if (opts.verifyOnChange) {
                let verifyArgs = opts.verify[formName];
                if (verifyArgs) {
                    isError = !$B._exeVerify(formName, newVal, verifyArgs, opts.$form);
                }
            }
            if (opts.onChange) {
                opts.onChange(formName, newVal, oldVal,isError);
            }
        };
    },
    /**
     * 验证一个表单项目
     * ***/
    _exeVerify: function (formName, newVal, verifyArgs, $form) {
        //console.log("exe verify ",newVal,formName,verifyArgs);
        let ret = [], res;
        if (Array.isArray(verifyArgs)) {
            for (let i = 0; i < verifyArgs.length; i++) {
                if (typeof verifyArgs[i] === "function") {
                    res = verifyArgs[i](formName, newVal, $form);
                } else {
                    res = $B._verify(verifyArgs[i], newVal);
                }
                if (res) {
                    ret.push(res);
                }
            }
        } else {
            if (typeof verifyArgs === "function") {
                res = verifyArgs(formName, newVal, $form);
            } else {
                res = $B._verify(verifyArgs, newVal);
            }
            if (res) {
                ret.push(res);
            }
        }
        let el = $B.DomUtils.findbyId($form, formName);
        if (!el) {
            el = $B.DomUtils.findbyId($form, "k_lbl_" + formName);
        }
        if (el) {
            let parentEl = el.parentNode;  
            if($B.Dom.css(parentEl,"display") === "inline-block" || $B.Dom.hasClass(parentEl.parentNode,"k_form_it_wrap")){
                parentEl = parentEl.parentNode;
            }
            let lplPrt = parentEl;
            let $row,$col,$item;
            let i = 0 ;
            while(i < 10 && lplPrt){
                if(lplPrt.nodeName === "BODY"){
                    break;
                }
                if($B.Dom.hasClass(lplPrt,"k_flow_form_item")){
                    $item = lplPrt;
                }
                if($B.Dom.hasClass(lplPrt,"k_flex_form_col")){
                    $col = lplPrt;
                }
                if($B.Dom.hasClass(lplPrt,"k_flex_form_row")){
                    $row = lplPrt;
                    break;
                }
                lplPrt = lplPrt.parentNode;
                i++;
            }           
            let errEl = $B.DomUtils.children(parentEl, ".k_verify_err_el");
            if (errEl.length == 0) {
                errEl = $B.DomUtils.append(parentEl, "<div style='display:none;position:relative;' class='k_verify_err_el'></div>");
            } else {
                errEl = errEl[0];
            }
            if (ret.length > 0) {
                let display = "inline-block";
                ret = $B.uniqueArray(ret);
                let errMsg = ret.join("; ");
                let len = $B.getCharWidth(errMsg) + 20;
                errEl.style.display = "none";
                errEl.style.width = len +"px";
                 //计算合适的位置
                if($row){ //flex布局表单                   
                    if(!$col.nextSibling && !$item.nextSibling){
                        let rwidth = $B.Dom.width($row);
                        let preWidth = 0;
                        while($col){
                            preWidth = preWidth + $B.Dom.outerWidth($col);
                            $col = $col.previousSibling;
                        }                     
                        let alvWidth = rwidth - preWidth;
                        if(alvWidth < len){
                            display = "block";
                            errEl.style.width = (alvWidth - 2) + "px";
                        }
                    }else{
                        let colWidth = $B.Dom.width($item) -2;
                        errEl.style.width = colWidth + "px";
                        display = "block";
                    }
                }           
                if ($B.DomUtils.hasClass(el, "k_combox_wrap")) {
                    $B.DomUtils.addClass(el.firstChild, "k_input_value_err");
                } else {
                    $B.DomUtils.addClass(el, "k_input_value_err");
                }
                errEl.innerText = errMsg;
                if(display === "inline-block"){
                    errEl.style.paddingLeft = "2px"; 
                }else{
                    errEl.style.paddingLeft = "0px"; 
                }
                errEl.style.display = display;
            } else {
                if ($B.DomUtils.hasClass(el, "k_combox_wrap")) {
                    $B.DomUtils.removeClass(el.firstChild, "k_input_value_err");
                } else {
                    $B.DomUtils.removeClass(el, "k_input_value_err");
                }
                errEl.style.display = "none";
            }
        }
        return ret.length === 0;
    },
    _verify: function (rule, val) {
        if ($B.config) {
            if (typeof rule === "string") {//内置的规则
                return $B._defaultVerify(val, rule);
            } else if ($B.isPlainObjectFn(rule)) {
                if (rule.rule) {//内置的规则
                    let ruleName = rule.rule;
                    let label = rule.label;
                    return $B._defaultVerify(val, ruleName, label, rule);
                } else if (rule.reg) {//自定义正则表达式                    
                    if (val !== "" && !rule.reg.test(val)) {
                        let label = $B.config.verify.regLabel;
                        if (rule.label) {
                            label = rule.label;
                        }
                        return label;
                    }
                }
            }
        }
    },
    _defaultVerify: function (val, ruleName, label, rule) {
        let vcfg = $B.config.verify;
        let cfg = vcfg[ruleName];
        if (cfg) {
            if (!label) {
                label = cfg.label;
            }
            if ("remote" === ruleName) {//远程验证
                console.log("远程验证 尚未实现！");
            } else if ("require" === ruleName) {
                if (Array.isArray(val)) {
                    if (val.length === 0) {
                        return label;
                    }
                } else {
                    val = $B.trimFn(val);
                    if (val === "") {
                        return label;
                    }
                }
            } else if ("range" === ruleName) {
                if (val !== "") {
                    if (!vcfg.number.reg.test(val)) {
                        return vcfg.number.label;
                    }
                    let min = rule.min;
                    let max = rule.max;
                    let number = parseFloat(val);
                    if (number < min || number > max) {
                        return label.replace("{1}", min).replace("{2}", max);
                    }
                }
            } else if ("minlength" === ruleName) {
                if (val !== "" && val.length < rule.len) {
                    return label.replace("{1}", rule.len);
                }
            } else if ("maxlength" === ruleName) {
                if (val !== "" && val.length > rule.len) {
                    return label.replace("{1}", rule.len);
                }
            } else {
                if (val !== "" && !cfg.reg.test(val)) {
                    return label;
                }
            }
        }
    },
    _arr2str: function (arr) {
        let tmp = [];
        for (let i = 0; i < arr.length; i++) {
            if (Array.isArray(arr[i])) {
                tmp.push(this._arr2str(arr[i]));
            } else {
                tmp.push(arr[i]);
            }
        }
        return tmp.join(";");
    },
    _loopFormEl: function (el, onLoopFn) {
        onLoopFn(el);
        var children = el.children;
        for (let i = 0; i < children.length; i++) {
            let child = children[i];
            this._loopFormEl(child, onLoopFn);
        }
    },
    uniqueArray: function (arr) {
        return Array.from(new Set(arr));
    },
    /**
     * 生成16位的对称加密key
     * **/
    AESGenKey: function (length = 16) {
        let random = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        let str = "";
        for (let i = 0; i < length; i++) {
            str = str + random.charAt(Math.random() * random.length)
        }
        return str;
    },
    /**
     * des加密 依赖于encrypt-min.js
     * ***/
    AESEncrypt: function (plaintext, key) {
        if (typeof window["CryptoJS"] === "undefined") {
            console.log("没有加载 》》 CryptoJS");
            return message;
        }
        if (plaintext instanceof Object) {
            plaintext = JSON.stringify(plaintext)
        }
        let encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(plaintext),
            CryptoJS.enc.Utf8.parse(key),
            { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 });
        return encrypted.toString();
    },
    /**
     * des解密
     * **/
    AESDecrypt: function (ciphertext, key) {
        if (typeof window["CryptoJS"] === "undefined") {
            console.log("没有加载 》》 CryptoJS");
            return message;
        }
        let decrypt = CryptoJS.AES.decrypt(ciphertext, CryptoJS.enc.Utf8.parse(key),
            { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 });
        let decString = CryptoJS.enc.Utf8.stringify(decrypt).toString();
        if (decString.charAt(0) === "{" || decString.charAt(0) === "[") {
            decString = JSON.parse(decString);
        }
        return decString;
    },
    //RSA 位数，这里要跟后端对应
    RSAGenKeys: function (bits = 1024) {
        if (typeof window["JSEncrypt"] === "undefined") {
            console.log("没有加载 JSEncrypt");
            return message;
        }
        let genKeyPair = {};
        if (!this.genKeyPairGener) {
            let genKeyPairGen = new JSEncrypt({ default_key_size: bits });
            this.genKeyPairGener = genKeyPairGen;
        }
        //获取私钥
        genKeyPair.privateKey = this.genKeyPairGener.getPrivateKey();//.replace("----BEGIN RSA PRIVATE KEY-----\n","").replace("\n-----END RSA PRIVATE KEY-----","");
        //获取公钥
        genKeyPair.publicKey = this.genKeyPairGener.getPublicKey();//.replace("-----BEGIN PUBLIC KEY-----\n","").replace("\n-----END PUBLIC KEY-----","");       
        return genKeyPair;
    },
    //公钥加密
    RSAEncrypt: function (plaintext, publicKey) {
        if (!this.genKeyPairGener) {
            alert("please invoke RSAGenKeys !");
            return;
        }
        if (plaintext instanceof Object) {
            plaintext = JSON.stringify(plaintext)
        }
        publicKey && this.genKeyPairGener.setPublicKey(publicKey);
        return this.genKeyPairGener.encryptLong(plaintext);
    },
    //私钥解密
    RSADecrypt: function (ciphertext, privateKey) {
        if (!this.genKeyPairGener) {
            alert("please invoke RSAGenKeys !");
            return;
        }
        privateKey && this.genKeyPairGener.setPrivateKey(privateKey);
        let decString = this.genKeyPairGener.decryptLong(ciphertext);
        if (decString.charAt(0) === "{" || decString.charAt(0) === "[") {
            decString = JSON.parse(decString);
        }
        return decString;
    },
    bindInputClear: function (form, onClearFn) {
        if (typeof form === "string") {
            form = document.getElementById(form.replace("#", ""));
        }
        let inputs = $B.DomUtils.findByTagName(form, "input[type=text]");
        let pws = $B.DomUtils.findByTagName(form, "input[type=password]");
        let textArea = $B.DomUtils.findByTagName(form, "textarea");
        if (!window["_inputClearEvs"]) {
            window["_inputClearEvs"] = {
                mouseenter: function (e) {
                    let $clearBtn = $B.DomUtils.findbyId(document.body, "#k_global_clear_btn");
                    if (!$clearBtn) {
                        $clearBtn = $B.DomUtils.createEl("<div id='k_global_clear_btn' style='position:absolute;display:none;z-index:2147483647;width:8px;height:14px;cursor:pointer;'><i style='color:#ccc;' class='fa  fa-cancel-1'></i></div>");
                        $B.DomUtils.append(document.body, $clearBtn);
                        $B.DomUtils.click($clearBtn, function () {
                            let el = this._el;
                            this.style.display = "none";
                            if (el) {
                                el.value = "";
                                this._el = undefined;
                                if (el.onClearFn) {
                                    if (!el.onClearFn(el.id)) {
                                        el.onClearFn = undefined;
                                    }
                                }
                                el.focus();
                            }
                        });
                    }
                    if (this.value !== "") {
                        let ofs = $B.DomUtils.offset(this);
                        let w = $B.DomUtils.outerWidth(this);
                        let h = $B.DomUtils.outerHeight(this);
                        ofs.top = ofs.top + (h - 20) / 2;
                        ofs.left = ofs.left + w - 10;
                        $B.DomUtils.css($clearBtn, ofs);
                        $clearBtn.style.display = "block";
                        $clearBtn._el = this;
                    }
                },
                mouseleave: function (e) {
                    let x = e.pageX;
                    let y = e.pageY;
                    let min = $B.DomUtils.offset(this);
                    let w = $B.DomUtils.outerWidth(this);
                    let h = $B.DomUtils.outerHeight(this);
                    let max = {
                        top: min.top + h,
                        left: min.left + w
                    };
                    if (!(x > min.left && x < max.left && y > min.top && y < max.top)) {
                        let $clearBtn = $B.DomUtils.findbyId(document.body, "#k_global_clear_btn");
                        if ($clearBtn) {
                            $clearBtn._el = undefined;
                            $clearBtn.style.display = "none";
                        }
                    }
                }
            };
        }
        Array.prototype.push.apply(inputs, pws);
        Array.prototype.push.apply(inputs, textArea);
        for (let i = 0, len = inputs.length; i < len; i++) {
            if (!$B.DomUtils.attribute(inputs[i], "readonly") && !$B.DomUtils.attribute(inputs[i], "disabled")) {
                let $in = inputs[i];
                if(!$B.Dom.getData($in,"clear_ev")){
                    let canBind = !$B.DomUtils.hasClass($in, "k_calendar_input") && !$B.DomUtils.hasClass($in, "k_combox_input")
                    &&  !$B.DomUtils.hasClass($in, "k_number_input");
                    if (canBind) {
                        $in.onClearFn = onClearFn;
                        $B.DomUtils.addClass($in, "k_box_size");
                        $B.DomUtils.css($in, { "padding-right": "10px" });
                        $B.DomUtils.bind($in, window["_inputClearEvs"]);
                        $B.DomUtils.setData($in,  "clear_ev", true );
                    }
                }             
            }
        }
    },
    /**
     * $wap: iframe容器
     * htmlEl: iframe内部的html
     * style:写入的样式
     * ***/
    createTextIfr: function ($wap, htmlEl, style, ifrCss) {
        let $ifr = $B.DomUtils.createEl('<iframe class="text_ifr" frameborder="0" style="width:100%;height:100%;" scrolling="no"></iframe>');
        if (ifrCss) {
            $B.DomUtils.css($ifr, ifrCss);
        }
        $B.DomUtils.append($wap, $ifr);
        var $body = $ifr.contentWindow.document.body;
        var $head = $ifr.contentWindow.document.head;
        $B.DomUtils.append($body, htmlEl);

        this._appendHeaderStyle($head, "base", "*{padding: 0;margin: 0;font-size: 14px;line-height: 1.5em;font-family: 'Microsoft Yahei', Helvetica, Arial, sans-serif;color: #1A242C;}"
            + "html,body{width:100%;height:100%}  *:focus {outline: none} textarea{padding: 2px 2px;text-align: left;border: 1px solid #ccc;} button{background: none;white-space: nowrap;border: 1px solid rgb(196, 224, 255);border-radius: 2px;padding: 1px 3px;line-height: 1.5em;cursor: pointer;font-size:13px;}"
            + "input::-webkit-input-placeholder，input::-moz-placeholder，input:-moz-placeholder，input:-ms-input-placeholder{color:#A9A9A9;}"
            + "input[type=text]:focus , input[type=password]:focus, textarea:focus{border-color: #409eff;} table{border-collapse: separate;border-spacing: 0;table-layout: fixed;} table td{padding:5px 2px;}"
            + "input.k_input_value_err,textarea.k_input_value_err,select.k_input_value_err{border:1px dashed #FF6E00 !important;}"
            + ".clearfix {*zoom:1;}.clearfix:before,.clearfix:after{display:table;line-height:0;content:'';} .clearfix:after{clear:both;}::-webkit-scrollbar{width:8px;height:8px;}::-webkit-scrollbar-button,::-webkit-scrollbar-button:vertical{display:none;}"
            + "::-webkit-scrollbar-track,::-webkit-scrollbar-track:vertical{box-shadow:inset006pxtransparent;background-color:transparent;}::-webkit-scrollbar-thumb,::-webkit-scrollbar-thumb:vertical{box-shadow:inset006pxrgba(100,173,250,.5);border-radius:6px;}"
            + "::-webkit-scrollbar-thumb:hover,::-webkit-scrollbar-thumb:vertical:hover{box-shadow:inset006pxrgba(100,173,250,.8);background-color:#74B9FF;}::-webkit-scrollbar-corner,::-webkit-scrollbar-corner:vertical{background-color:none;}"
            + "::-webkit-scrollbar-resizer,::-webkit-scrollbar-resizer:vertical{background-color:#ff6e00;}.ifr_inner_delbtn{position:relative;top:-5px;left:5px;}.ifr_inner_delbtn:before{content:'x';font-weight: bold;}"
            + 'select{border: solid 1px #ccc; appearance:none;-moz-appearance:none;-webkit-appearance: none;padding: 2px 12px 2px 2px;background: url("") no-repeat scroll right center transparent;}select::-ms-expand {display: none;}'
            + "input[type=text],input[type=password] {-webkit-appearance: textfield;background-color: white;-webkit-rtl-ordering: logical;user-select: text;cursor: auto;padding: 3px 2px;outline: none;border: 1px solid #ccc;line-height: 18px;box-sizing: border-box;font-size:13px;}");
        if (style) {
            let userStyle = style;
            if (Array.isArray(style)) {
                userStyle = style.join("");
            }
            this._appendHeaderStyle($head, "userstyle", userStyle);
        }
    },
    clearDomSelected: function () {
        try {
            if (document.selection) {
                document.selection.empty();
            } else if (window.getSelection) {
                window.getSelection().removeAllRanges();
            }
        } catch (r) { }
    },
    getInputVal: function (el, defVal) {
        let v = $B.trimFn(el.value);
        if (v === "" && typeof defVal !== "undefined") {
            return defVal
        }
        return v;
    },
    setSelectValue: function (el, val) {
        val = val + "";
        let childs = el.children;
        for (let i = 0; i < childs.length; i++) {
            if (childs[i].value === val) {
                $B.Dom.attr(childs[i], { selected: "selected" });
            } else {
                $B.Dom.removeAttr(childs[i], "selected");
            }
        }
    },
    /**
     * 按大写分隔字符，
     * splitStr：分隔符，空则返回数组
     * ***/
    splitByUper:function(txt,splitStr){
        let res;
        if(splitStr){
            res = txt.replace(/([A-Z])/g, splitStr+'$1').toLowerCase();
        }else{
            res = txt.split(/(?=[A-Z])/);
            for(let i =0 ;i < res.length;i++){
                res[i] = res[i].toLowerCase();
            }
        }
        return res;
    },
    str2camal:function(txt,splitStr){
        if(!splitStr){
            splitStr = "-";
        }
        let arr = txt.split(splitStr);
        for(let i = 0 ;i < arr.length ;i++){
            arr[i] = arr[i].toLowerCase();
            if(i > 0){
                arr[i] = arr[i].replace(/( |^)[a-z]/g,(L)=>L.toUpperCase());
            }
        }
        return arr.join("");
    }
});
/******定义一个基类
 * 封装基本的删除，情况，设置控件element的api
 * ******/
class BaseControl {
    constructor() {
        //console.log("BaseControl has bean call");
        this.id = $B.getUUID();
    }
    setElObj(args) {
        if (typeof args === "string") {
            args = args.replace("#", "");
            this.elObj = document.getElementById(args);
            this.id = args;
        } else {
            this.elObj = args;
            let id = $B.DomUtils.attribute(this.elObj, "id");
            if (id) {
                this.id = id;
            } else {
                this.id = $B.getUUID();
                $B.DomUtils.attribute(this.elObj, { "id": this.id });
            }
        }
        // if (!this.id) {
        //     this.id = $B.getUUID();
        // }
    }
    clearDom() {
        if (this.elObj) {
            $B.DomUtils.removeChilds(this.elObj);
        }
    }
    delProps(excuObjName) {
        for (var p in this) {
            if (this.hasOwnProperty(p)) {
                if (this[p] !== null && this[p] !== undefined) {
                    if (p !== "super" && typeof (this[p].destroy) === "function") {
                        if (!excuObjName || excuObjName !== this[p]) {
                            this[p].destroy(this);
                        }
                    }
                }
                delete this[p];
            }
        }
    }
    destroy(excuObjName) {
        if (this.elObj) {
            $B.DomUtils.remove(this.elObj);
            this.elObj = undefined;
        }
        this.delProps(excuObjName);
    }
    clearProps() {
        for (var p in this) {
            if (this.hasOwnProperty(p)) {
                delete this[p];
            }
        }
    }
    clear() {
        this.clearDom();
        this.delProps();
    }
}
$B["BaseControl"] = BaseControl;
//设置一个用于a标签下载指向的iframe
var count = 0;
var itv001 = setTimeout(function () {
    let $body = document.body;
    if ($body) {
        clearInterval(itv001);
        if (!$B.Dom.findbyId($body, "k_down_load_ifr")) {
            let isLoadding = false;
            let ifr = $B.Dom.createEl('<iframe  name="k_down_load_ifr" id="k_down_load_ifr" frameborder="0" style="display:none;vertical-align:top;" scroll="none" width="0" height="0" ></iframe>');
            $B.Dom.append($body, ifr);
            $B.DomUtils.onload(ifr, () => {
                if (isLoadding) {
                    $B.error($B.config.file404, 2);
                }
            });
            setTimeout(function () {
                isLoadding = true;
            }, 300);
        }
    }
    count++;
    if (count > 20) {
        clearInterval(itv001);
    }
}, 300);